package com.nttuan.service2;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import com.nttuan.model.dao.ContactDao;
import com.nttuan.model.dao.TaskDao;
import com.nttuan.model.dao.TrackDao;
import com.nttuan.model.dao.UserDao;
import com.nttuan.model.dao.service.ContactService;
import com.nttuan.model.dao.service.TaskService;
import com.nttuan.model.dao.service.TrackService;
import com.nttuan.model.dao.service.UserService;
import com.nttuan.model.entity.Contact;
import com.nttuan.model.entity.Task;
import com.nttuan.model.entity.Track;
import com.nttuan.model.entity.User;
import com.nttuan.mycalender.AddNewActivity;
import com.nttuan.mycalender.MainActivity;
import com.nttuan.mycalender.NotificationActivity;
import com.nttuan.mycalender.R;
import com.nttuan.util.JSONParser;
import com.nttuan.util.LogSupport;
import com.nttuan.util.Network;
import com.nttuan.util.ServiceSupport;
import com.nttuan.util.Support;

import org.json.JSONObject;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by TuanNT on 12/1/2014.
 */
public class NotificationService extends Service {
    private static final String TAG ="NotificationService";
    private final int DELAY = 6000;
    public static String ACTION = "action";

    private Context context;
    private Timer timer;
    private RefreshNotification refreshNotification;
    private TrackService trackService;
    private TaskService taskService;
    private ContactService contactService;
    private boolean appRunning = false;


    @Override
    public void onCreate() {
        this.context = NotificationService.this;
        this.trackService = TrackDao.getInstance(context);
        this.taskService = TaskDao.getInstance(context);
        this.contactService = ContactDao.getInstance(context);
        this.timer = new Timer();
        this.refreshNotification = new RefreshNotification();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.timer.scheduleAtFixedRate(refreshNotification, 0, DELAY);
        Log.d(TAG, "started");
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        timer.cancel();
        refreshNotification.cancel();
        Log.d(TAG,"Stop service");
    }

    class RefreshNotification extends TimerTask {
        private List<Track> tracks;
        private Date lastUpdate;
        private Date temp;
        public RefreshNotification(){
            lastUpdate = LogSupport.lastTimeNotifi(context);
        }
        @Override
        public void run() {
            tracks = trackService.tracks(lastUpdate);
            int numberOfMessage= tracks.size();
            if (ServiceSupport.activityRunning(context,"com.nttuan.mycalender.MainActivity")) {
                if (numberOfMessage > 0) {
                    sendMyBroadcast(numberOfMessage);
                }
            }else {
                //running in background
                showNotification(tracks);
            }
            if(numberOfMessage > 0) {
                lastUpdate = tracks.get(0).getLastTime();
            }
            if(Network.isConnect(context)) {
                tracks = trackService.tracksSend();
                sendToServer(tracks);
            }
        }
        private void showNotification(List<Track> list){
            for(Track track: list){
                switch (track.getActon()){
                    case Track.ACTION_ALARM:
                        notificationAlarm(track.getTask());
                        break;
                    case Track.ACTION_EVENT_START:
                        notificationStarted(track.getTask());
                        break;
                    case Track.ACTION_RECEIVE_INVITE:
                        notificationInvite(track.getTask(), track.getMessage());
                        break;
                    case Track.ACTION_RECEIVE_ACCEPT:
                        notificationAccept(track.getTask(),track.getMessage());
                        break;
                    case Track.ACTION_RECEIVE_DELETE_INVITE:
                        notificationDelete(track.getTask(),track.getMessage());
                        break;
                    case Track.ACTION_RECEIVE_UPDATE_INVITE:
                        notificationUpdateInvite(track.getTask(),track.getMessage());
                        break;
                }
            }
        }
        private void sendToServer(List<Track> list){
            for(Track track : list){
                switch (track.getActon()){
                    case Track.ACTION_SEND_INVITE:
                        sendInvite(track);
                        break;
                    case Track.ACTION_SEND_ACCEPT:
                        sendAcceptInvite(track);
                        break;
                    case Track.ACTION_UPDATE_INVITE:
                        sendUpdateInvite(track);
                        break;
                    case Track.ACTION_DELETE_INVITE:
                        deleteTask(track);
                        break;
                }
            }
        }
        private void deleteTask(Track track){
            Log.d(TAG, "send deleteTask start");
            JSONObject root = JSONParser.sendDelete(track);
            try{
                String result = root.getString("result");
                if(result.equals("1")){
                    trackService.commit(track.getTrackId(), true);
                    Log.d(TAG, "send deleteTask: success");
                }else
                    Log.d(TAG, "send deleteTask: fail");
            }catch (Exception e){
                Log.d(TAG, "deleteTask:" +e.toString());
            }
        }
        private void sendUpdateInvite(Track track){
            Task task = track.getTask();
            task.setListContact(contactService.contactsByTask(task.getTaskId()));
            JSONObject root = JSONParser.sendTask(task,Track.ACTION_UPDATE_INVITE,track.getMessage());
            try {
                String result = root.getString("result");
                if(result.equals("1")){
                    trackService.commit(track.getTrackId(), true);
                    Log.d(TAG, "sendUpdateInvite: success");
                }else
                    Log.d(TAG, "sendUpdateInvite: fail");
            }catch (Exception c){
                Log.d(TAG, "sendUpdateInvite:" +c.toString());
            }
        }
        private void sendAcceptInvite(Track track){
            UserService userService = UserDao.getInstance(context);
            JSONObject root = JSONParser.sendAcceptInvite(userService.getMe().getEmail(),track.getTask().getPublicId());
            try{
                String result = root.getString("result");
                if(result.equals("1")){
                    trackService.commit(track.getTrackId(), true);
                    Log.d(TAG, "sendAcceptInvite: success");
                }
            }catch (Exception e){
                Log.d(TAG, "sendAcceptInvite:" +e.toString());
            }
        }
        private void sendInvite(Track track){
            Task task = track.getTask();
            task.setListContact(contactService.contactsByTask(task.getTaskId()));
            JSONObject root = JSONParser.sendTask(task, Track.ACTION_SEND_INVITE,track.getMessage());
            if(root == null)
                return;
            Log.d("sendInvite test", root.toString());
            try {
                String result = root.getString("result");
                if(result.equals("1")){
                    taskService.createPublicId(root.getInt(Task.TASK_ID) ,root.getInt(Task.PUBLIC_ID));
                    trackService.commit(track.getTrackId(), true);
                    Log.d(TAG, "sendInvite: success");
                }
            }catch (Exception c){
                Log.d(TAG, "sendInvite:" +c.toString());
            }
        }
        private void sendMyBroadcast(int numberOfMessage){
            Intent intent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(MainActivity.NUMBER_OF_NOTIFICATION, numberOfMessage);
            intent.putExtra(MainActivity.PACKET, bundle);
            intent.setAction(ACTION);
            sendBroadcast(intent);
        }
        private void notificationUpdateInvite(Task task, String message){
            String title = task.getTaskName();
            message = context.getText(R.string.message_update_invite).toString();
            Intent intent = new Intent(context, AddNewActivity.class);
            Bundle bundle = new Bundle();
            bundle.putInt(AddNewActivity.KEY_TASK_ID, task.getTaskId());
            bundle.putInt(AddNewActivity.KEY_ACTION,AddNewActivity.KEY_ACTION_VIEW_INVITE);
            intent.putExtra(AddNewActivity.KEY_BUNDLE, bundle);
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            buildNotification(contentIntent, title, message , R.drawable.ic_launcher);
        }
        private void notificationDelete(Task task, String message){
            String title =getString(R.string.title_notifi_canceled, task.getTaskName());
            Intent intent = new Intent(context, AddNewActivity.class);
            Bundle bundle = new Bundle();
            bundle.putInt(AddNewActivity.KEY_TASK_ID, task.getTaskId());
            bundle.putInt(AddNewActivity.KEY_ACTION,AddNewActivity.KEY_ACTION_VIEW);
            intent.putExtra(AddNewActivity.KEY_BUNDLE, bundle);
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            buildNotification(contentIntent, title, message , R.drawable.ic_launcher);
        }
        private void notificationAccept(Task task, String message){
            String title = task.getTaskName();
            Intent intent = new Intent(context, AddNewActivity.class);
            Bundle bundle = new Bundle();
            bundle.putInt(AddNewActivity.KEY_TASK_ID, task.getTaskId());
            bundle.putInt(AddNewActivity.KEY_ACTION,AddNewActivity.KEY_ACTION_VIEW);
            intent.putExtra(AddNewActivity.KEY_BUNDLE, bundle);
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            buildNotification(contentIntent, title, message , R.drawable.ic_launcher);
        }
        private void notificationInvite(Task task, String message){
            String title = getString(R.string.title_notifi_invite);
            if(message == null)
                message ="";
            if(message.equals(""))
               message = getString(R.string.title_invite_defaule);
            Intent intent = new Intent(context, AddNewActivity.class);
            Bundle bundle = new Bundle();
            bundle.putInt(AddNewActivity.KEY_TASK_ID, task.getTaskId());
            bundle.putInt(AddNewActivity.KEY_ACTION,AddNewActivity.KEY_ACTION_VIEW_INVITE);
            intent.putExtra(AddNewActivity.KEY_BUNDLE, bundle);
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            buildNotification(contentIntent, title, message , R.drawable.ic_launcher);
        }
        private void notificationStarted(Task task){
            String title = task.getTaskName();
            String message = getString(R.string.title_notifi_stared_where);
            Intent intent = new Intent(context, NotificationActivity.class);
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            buildNotification(contentIntent, title, message , R.drawable.ic_launcher);
        }
        private void notificationAlarm(Task task){
            String title = task.getTaskName();
            String message;
            if(task.getRemind() < 1440)
                message = getString(R.string.title_notifi_alarm_today, Support.displayTime(task.getStart()));
            else {
                String start = Support.displayTime(task.getStart());
                String end = Support.displayTime(task.getEnd());
           //     message = getString(R.string.title_notifi_alarm2, start, end, Support.displayDate(task.getStart()));
                if (task.getRepeat() != null && !task.getRepeat().equals(""))
                    message = getString(R.string.title_notifi_repeat, start, end, Support.displayRepeat(context, task.getRepeat()));
                else
                    message = getString(R.string.title_notifi_alarm2, start, end, Support.displayDate(task.getStart()));
            }
            Intent intent = new Intent(context, NotificationActivity.class);
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            buildNotification(contentIntent, title, message , R.drawable.ic_launcher);

        }
        private void buildNotification(PendingIntent pendingIntent,String title, String message, int icon) {
            Notification.Builder builder = new Notification.Builder(context);
            StringBuilder content = new StringBuilder();
            builder.setContentTitle(title);
            builder.setSmallIcon(R.drawable.ic_launcher);
            builder.setContentText(message);
            builder.setContentIntent(pendingIntent);
            builder.setAutoCancel(true);
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT < 16)
                notificationManager.notify(1, builder.getNotification());
            if (Build.VERSION.SDK_INT > 15)
                notificationManager.notify(1, builder.build());
        }
    }

    public void setAppRunning(boolean appRunning) {
        this.appRunning = appRunning;
    }

}
